package com.crm.service.client.impl;

import com.alibaba.druid.util.StringUtils;
import com.crm.dao.client.ClientInfoDao;
import com.crm.dao.client.ClientTransferDao;
import com.crm.dao.client.ContactDao;
import com.crm.dao.permission.UserInfoDAO;
import com.crm.excel.upload.ClientInfoExcel;
import com.crm.exception.ServiceException;
import com.crm.pojo.ClientInfo;
import com.crm.pojo.ClientTransfer;
import com.crm.pojo.Contact;
import com.crm.pojo.Userinfo;
import com.crm.service.client.ClientInfoService;
import com.crm.vo.ClientContactVO;
import com.crm.vo.ClientGroupCountVo;
import com.crm.vo.Result;
import com.sun.javafx.logging.PulseLogger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class ClientInfoServiceImpl implements ClientInfoService {

    @Autowired
    public ClientInfoDao clientInfoDao;
    @Autowired
    public ContactDao contactDao;
    @Autowired
    public UserInfoDAO userInfoDao;
    @Autowired
    public  ClientTransferDao clientTransferDao;
    @Autowired
    private EntityManager entityManager;

    @Override
    public List<ClientInfo> findAllNotDelByUserId(BigDecimal userId) {

        return (List<ClientInfo>) clientInfoDao.findAllNotDelByUserId(userId);
    }

    @Override
    public List<ClientInfo> queryByClientInfo(ClientInfo clientInfo, int curpage, int pagesize,
                                              Date createStartTime, Date createEndTime, Date updateStartTime, Date updateEndTime) {
        Assert.notNull(clientInfo);
        PageRequest page = new PageRequest(curpage - 1, pagesize, Sort.Direction.DESC, "updateDate");
        @SuppressWarnings("unchecked")
        Page<ClientInfo> result = clientInfoDao.findAll(new Specification<ClientInfo>() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery arg1, CriteriaBuilder cb) {


                List<Predicate> list = new ArrayList<>();
                //根据以下条件查询
                //客户编号
                if (clientInfo.getCid() != null) {
                    list.add(cb.equal(root.get("cid").as(BigDecimal.class), clientInfo.getCid()));
                }

                //客户名称
                if (!StringUtils.isEmpty(clientInfo.getCname())) {
                    list.add(cb.like(root.get("cname").as(String.class), "%" + clientInfo.getCname() + "%"));
                }

                //用户阶段
                if (!StringUtils.isEmpty(clientInfo.getStage())) {
                    list.add(cb.like(root.get("stage").as(String.class), "%" + clientInfo.getStage() + "%"));
                }

                //用户种类
                if (!StringUtils.isEmpty(clientInfo.getType())) {
                    list.add(cb.like(root.get("type").as(String.class), "%" + clientInfo.getType() + "%"));
                }

                //关系等级
                if (!StringUtils.isEmpty(clientInfo.getRelationship())) {
                    list.add(cb.like(root.get("relationship").as(String.class), "%" + clientInfo.getRelationship() + "%"));
                }

                //来源
                if (!StringUtils.isEmpty(clientInfo.getSource())) {
                    list.add(cb.like(root.get("source").as(String.class), "%" + clientInfo.getSource() + "%"));
                }

                //行业
                if (!StringUtils.isEmpty(clientInfo.getIndustry())) {
                    list.add(cb.like(root.get("industry").as(String.class), "%" + clientInfo.getIndustry() + "%"));
                }

                //人员规模
                if (!StringUtils.isEmpty(clientInfo.getScale())) {
                    list.add(cb.like(root.get("scale").as(String.class), "%" + clientInfo.getScale() + "%"));
                }

                //信用等级
                if (!StringUtils.isEmpty(clientInfo.getCredit())) {
                    list.add(cb.like(root.get("credit").as(String.class), "%" + clientInfo.getCredit() + "%"));
                }

                //用户编号
                if (clientInfo.getUserId() != null) {
                    list.add(cb.equal(root.get("userId").as(BigDecimal.class), clientInfo.getUserId()));
                }

                //电话
                if (!StringUtils.isEmpty(clientInfo.getPhone())) {
                    list.add(cb.like(root.get("phone").as(String.class), "%" + clientInfo.getPhone() + "%"));
                }

                //传真
                if (!StringUtils.isEmpty(clientInfo.getFax())) {
                    list.add(cb.like(root.get("fax").as(String.class), "%" + clientInfo.getFax() + "%"));
                }

                //网址
                if (!StringUtils.isEmpty(clientInfo.getUrl())) {
                    list.add(cb.like(root.get("url").as(String.class), "%" + clientInfo.getUrl() + "%"));
                }

                //时间段查询创建日期
                //起始日期
                if (createStartTime != null) {
                    list.add(cb.greaterThanOrEqualTo(root.get("createDate").as(Date.class), createStartTime));
                }
                //结束日期
                if (createEndTime != null) {
                    list.add(cb.lessThanOrEqualTo(root.get("createDate").as(Date.class), createEndTime));
                }

                //地址
                if (!StringUtils.isEmpty(clientInfo.getAddress())) {
                    list.add(cb.like(root.get("address").as(String.class), "%" + clientInfo.getAddress() + "%"));
                }

                //备注
                if (!StringUtils.isEmpty(clientInfo.getRemarks())) {
                    list.add(cb.like(root.get("remarks").as(String.class), "%" + clientInfo.getRemarks() + "%"));
                }

                //时间段查询更新日期
                //起始日期
                if (updateStartTime != null) {
                    list.add(cb.greaterThanOrEqualTo(root.get("updateDate").as(Date.class), updateStartTime));
                }
                //结束日期
                if (updateEndTime != null) {
                    list.add(cb.lessThanOrEqualTo(root.get("updateDate").as(Date.class), updateEndTime));
                }

                //没有被删除
                list.add(cb.notLike(root.get("clientInfoIsDel").as(String.class), "是"));

                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
            }
        }, page);

        List<ClientInfo> list = result.getContent();
        return list;

    }


    @Override
    public Long queryNumByClientInfo(ClientInfo clientInfo, Date createStartTime, Date createEndTime
            , Date updateStartTime, Date updateEndTime) {
        Assert.notNull(clientInfo);
        Long count = clientInfoDao.count(new Specification<ClientInfo>() {

            @Override
            public Predicate toPredicate(Root<ClientInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

                List<Predicate> list = new ArrayList<>();
                //根据以下条件查询
                //客户编号
                if (clientInfo.getCid() != null) {
                    list.add(cb.equal(root.get("cid").as(BigDecimal.class), clientInfo.getCid()));
                }

                //客户名称
                if (!StringUtils.isEmpty(clientInfo.getCname())) {
                    list.add(cb.like(root.get("cname").as(String.class), "%" + clientInfo.getCname() + "%"));
                }

                //用户阶段
                if (!StringUtils.isEmpty(clientInfo.getStage())) {
                    list.add(cb.like(root.get("stage").as(String.class), "%" + clientInfo.getStage() + "%"));
                }

                //用户种类
                if (!StringUtils.isEmpty(clientInfo.getType())) {
                    list.add(cb.like(root.get("type").as(String.class), "%" + clientInfo.getType() + "%"));
                }

                //关系等级
                if (!StringUtils.isEmpty(clientInfo.getRelationship())) {
                    list.add(cb.like(root.get("relationship").as(String.class), "%" + clientInfo.getRelationship() + "%"));
                }

                //来源
                if (!StringUtils.isEmpty(clientInfo.getSource())) {
                    list.add(cb.like(root.get("source").as(String.class), "%" + clientInfo.getSource() + "%"));
                }

                //行业
                if (!StringUtils.isEmpty(clientInfo.getIndustry())) {
                    list.add(cb.like(root.get("industry").as(String.class), "%" + clientInfo.getIndustry() + "%"));
                }

                //人员规模
                if (!StringUtils.isEmpty(clientInfo.getScale())) {
                    list.add(cb.like(root.get("scale").as(String.class), "%" + clientInfo.getScale() + "%"));
                }

                //信用等级
                if (!StringUtils.isEmpty(clientInfo.getCredit())) {
                    list.add(cb.like(root.get("credit").as(String.class), "%" + clientInfo.getCredit() + "%"));
                }

                //用户编号
                if (clientInfo.getUserId() != null) {
                    list.add(cb.equal(root.get("userId").as(BigDecimal.class), clientInfo.getUserId()));
                }

                //电话
                if (!StringUtils.isEmpty(clientInfo.getPhone())) {
                    list.add(cb.like(root.get("phone").as(String.class), "%" + clientInfo.getPhone() + "%"));
                }

                //传真
                if (!StringUtils.isEmpty(clientInfo.getFax())) {
                    list.add(cb.like(root.get("fax").as(String.class), "%" + clientInfo.getFax() + "%"));
                }

                //网址
                if (!StringUtils.isEmpty(clientInfo.getUrl())) {
                    list.add(cb.like(root.get("url").as(String.class), "%" + clientInfo.getUrl() + "%"));
                }

                //时间段查询创建日期
                //起始日期
                if (createStartTime != null) {
                    list.add(cb.greaterThanOrEqualTo(root.get("createDate").as(Date.class), createStartTime));
                }
                //结束日期
                if (createEndTime != null) {
                    list.add(cb.lessThanOrEqualTo(root.get("createDate").as(Date.class), createEndTime));
                }

                //地址
                if (!StringUtils.isEmpty(clientInfo.getAddress())) {
                    list.add(cb.like(root.get("address").as(String.class), "%" + clientInfo.getAddress() + "%"));
                }

                //备注
                if (!StringUtils.isEmpty(clientInfo.getRemarks())) {
                    list.add(cb.like(root.get("remarks").as(String.class), "%" + clientInfo.getRemarks() + "%"));
                }

                //时间段查询更新日期
                //起始日期
                if (updateStartTime != null) {
                    list.add(cb.greaterThanOrEqualTo(root.get("updateDate").as(Date.class), updateStartTime));
                }
                //结束日期
                if (updateEndTime != null) {
                    list.add(cb.lessThanOrEqualTo(root.get("updateDate").as(Date.class), updateEndTime));
                }

                //没有被删除
                list.add(cb.notLike(root.get("clientInfoIsDel").as(String.class), "是"));

                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
            }
        });
        return count;
    }


    @Override
    public Map addClientAndContract(String cname, String contactName, String source, String phone, String tel,
                                       String remarks, Date createDate, Date updateDate, BigDecimal userId) throws ServiceException {
    	Map map = new HashMap<>();
        try {
            List<ClientInfo> list = clientInfoDao.findClintInfoByCname(cname);
            if (list != null && list.size() != 0) {
                map.put("result", new Result("该客户已经存在"));
            } else {
                ClientInfo clientInfo = new ClientInfo();
                clientInfo.setCname(cname);
                clientInfo.setSource(source);
                clientInfo.setPhone(phone);
                clientInfo.setRemarks(remarks);
                clientInfo.setCreateDate(createDate);
                clientInfo.setUpdateDate(updateDate);
                clientInfo.setUserId(userId);
                clientInfo.setStage("潜在");
                clientInfo.setType("客户");
                clientInfo.setClientInfoIsDel("否");

                Contact contact = new Contact();
                contact.setContactName(contactName);
                contact.setPhone(phone);
                contact.setHomePhone(tel);
                contact.setType("主联系人");
                contact.setIsDel("否");
                contact.setClientInfo(clientInfo);


                clientInfoDao.save(clientInfo);
                contactDao.save(contact);
                map.put("result", Result.SUCCESS);
                map.put("clientInfo", clientInfo);
            }

        } catch (Exception e) {
            e.printStackTrace();
            map.put("result",  new Result("亲，添加失败！"));
        }
        return map;
    }


    @Override
    public Result delClient(Long cid) {
        try {
            if (cid == null) return new Result("亲，你还要选择要删除的客户！");
            ClientInfo clientInfo = clientInfoDao.findOne(cid);
            clientInfo.setClientInfoIsDel("是");
            clientInfo.setUpdateDate(new Date());
            List<Contact> contacts = clientInfo.getContacts();
            for (Contact contact : contacts) {
            	contact.setIsDel("是");
            	contactDao.save(contact);
			}
            List<ClientTransfer> clientTransfers = clientInfo.getClientTransfers();
            for (ClientTransfer clientTransfer : clientTransfers) {
            	clientTransfer.setClientTransferIsDel("是");
            	clientTransferDao.save(clientTransfer);
			}
            clientInfoDao.save(clientInfo);
            return Result.SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return new Result("亲，删除失败！");
        }
    }

    /**
     * 获取所有的客户信息
     *
     * @return
     */

    @Override
    public List<ClientInfo> getClientInfoList() {
        List<ClientInfo> list = new ArrayList<>();
        clientInfoDao.findAll().forEach(e -> list.add(e));
        return list;
    }

    @Override
    public List<Contact> queryContactByCid(Long cid) {
        List<ClientContactVO> list = clientInfoDao.getClientContactList(cid);
        List<Contact> contactList = new ArrayList<>();
        if (list.size() > 0) {
            for (ClientContactVO clientContactVO : list) {
                contactList.add(clientContactVO.getContact());
            }
        }
        return contactList;
    }


    @Override
    public Result editClient(ClientInfo clientInfo) {
        try {
            clientInfo.setUpdateDate(new Date());
            clientInfoDao.save(clientInfo);
            return Result.SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return new Result("亲，对不起，编辑失败！");
        }
    }


    @Override
    public List<Userinfo> queryAllUser() {
        List<Userinfo> list = (List<Userinfo>) userInfoDao.findAll();
        return list;
    }

	@Override
	public List<ClientInfo> findAllNotDel() {
		return clientInfoDao.findAllNotDel();
	}

	@Override
	public String userName(Long uId) {
		try {
			if(uId != null) {
				Userinfo userinfo = userInfoDao.findOne(uId);
				return userinfo.getUname();
			}else {
				return "";
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new ServiceException("亲，查询用户名失败！");
		}
	}

	@Override
	public ClientInfo load(Long cid) {
		return clientInfoDao.findOne(cid);
	}

    //模糊查询所有采购商根据采购商名称
    public List<ClientInfo> findAllClientByMh(String q){
        return clientInfoDao.findClintInfoBymh("%"+q+"%");
    }
    //查询一个供应商信息
    public ClientInfo findOne(Long cid){
        return clientInfoDao.findOne(cid);
    }

	@Override
	public Result uploadExcelClinetInfo(MultipartFile file, String uploadWay) {
		try {
			//创建处理EXCEL的类
			ClientInfoExcel clientInfoExcel = new ClientInfoExcel();
			//解析excel，获取上传的事件单,拿到所有信息
			List<ClientInfo> clientInfos = clientInfoExcel.getExcelInfo(file);
			//信息集合不为空，保存到数据库中
			if (clientInfos != null && !clientInfos.isEmpty()) {
				if ("新建式导入".equals(uploadWay)) {
					//新建式导入，直接创建
					for (ClientInfo clientInfo : clientInfos) {
						if (clientInfo.getCname()!=null) {
							List<ClientInfo> list = clientInfoDao.findClintInfoByCname(clientInfo.getCname());
				            if (list == null || list.size() == 0) {
				            	clientInfoDao.save(clientInfo);
				            }
						}
						
					}
				} else {
					//覆盖式导入，相同得则覆盖，不相同得新建
					for (ClientInfo clientInfo : clientInfos) {
						List<ClientInfo> list = clientInfoDao.findClintInfoByCname(clientInfo.getCname());
						if (list != null && list.size() != 0) {
							for (ClientInfo clientInfo2 : list) {
								clientInfo.setCid(clientInfo2.getCid());
								clientInfoDao.save(clientInfo);
							}
						}else {
							clientInfoDao.save(clientInfo);
						}
					}
				}
				return Result.SUCCESS;
			}else {
				return new Result("上传失败！");
			}
		} catch (Exception e) {
			e.printStackTrace();
			return new Result("上传失败！");
		}
	}

	@Override
	public List<ClientInfo> findAll() {
		return (List<ClientInfo>) clientInfoDao.findAll();
	}

	@Override
	public List<ClientGroupCountVo> selClientGroupCountVo(String factor) {
		 CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		 CriteriaQuery<ClientGroupCountVo> criteriaQuery = criteriaBuilder.createQuery(ClientGroupCountVo.class);
		 Root<ClientInfo> root = criteriaQuery.from(ClientInfo.class);
		 Expression<String> groupByExp = root.get(factor).as(String.class);
	     Expression<Long> countExp = criteriaBuilder.count(groupByExp);
	     CriteriaQuery<ClientGroupCountVo> select =
	              criteriaQuery.multiselect(groupByExp, countExp);
	     criteriaQuery.groupBy(groupByExp);
		 TypedQuery<ClientGroupCountVo> query = entityManager.createQuery(select);
	     List<ClientGroupCountVo> resultList = query.getResultList();
	     return resultList;
	}


}
